/*
 * ManagerResource.h
 *
 *  Created on:
 *      Author: Andrey Efimov
 *   Copyright: LGPL
 */

#ifndef _MANAGERRESOURCE_H_
#define _MANAGERRESOURCE_H_

#include <stdio.h>
#include <string>
#include <vector>
#include "../StructSource.h"
#include "../BasicTypes.h"
#include "../Visualisator/ShaderTypes.h"
#include "../Kernel/Logic/IGameLogic.h"

#include "ResourceWarehouse.h"
#include "CGameWorld.h"

using namespace std;

class CResourceLoader;

class ResourceOwner
{
private:

	static CResourceLoader* ResourceLoader;

	static CResourceWarehouse* ResourceWarehouse;

public:
	static CResourceLoader* GetResourceLoader();
    static void DeleteResourceLoader();

    static CResourceWarehouse* GetResourceWarehouse();
    static void DeleteResourceWarehouse();
};

//---------------------------------------------------

class CResourceLoader
{
friend class ResourceOwner;
private:
	struct SmdModel
	{
		STANDART_VERTEX                *vertices;
		GLushort                       *indexes;
		UINT                            vertexCount;
		GLsizei                         triangleCount;
		std::vector<TEXTURE_DESCRIPTOR> textures;

		SmdModel():vertexCount(0),triangleCount(0){};
		virtual ~SmdModel(){
								if ( NULL != vertices ) delete[] vertices;
								if ( NULL != indexes ) delete[] indexes;
						   };
	};

	struct SubobjectConstructionInfo
	{
		string         				name;
		string         				modelName;
		vector< pair<string,string> > textures;
		vector< pair<string,string> > animations;
	};

	struct UnitTypeInfo
	{
		struct SubobjectConfiguration
		{
			string          subobjectName;
			glm::vec3       relativePosition;
			glm::vec3       relativeOrientation;
			glm::vec3       dimesionSizes;
			IShaderProgram *shaderProgram;
		};

		string                         name;
		UNIT_TYPES                     unitType;
		vector<SubobjectConfiguration> subobjects;
	};

private:
	CResourceLoader();
	virtual ~CResourceLoader(){};

	vector<PURE_COMPRESSED_MODEL*> compressedModelsAray;
	static vector<IShaderParamParser*> *shaderParamParsers;

	static const UINT FILE_STRING_MAX_LENGHT = 300;
	static const UINT FILE_TOKEN_MAX_LENGHT = 128;

	static const string GUI_SUOBJECT_NAME;
	static const string GUI_SHADER_PROGRAM;

private:

	void ParseVertex( const char* VertString, STANDART_VERTEX *Target );
	SmdModel* CompressBuffersToModel( const STANDART_VERTEX *Vertices, const UINT VertCount );
	SmdModel* LoadSMDModel( const char* FileName );
	void CalculateGabarits( const SmdModel& Model, float &DimensionSphereRadius,
							glm::vec3 &DimensionSphereCenter, glm::vec3 &DimentionCorner );

	void ReadTexturesFromFile( FILE *file, vector<string> &TextureNames, vector< pair<GLuint,GLenum> > &TextureIDs );
	RENDER_MODEL_INFO* LoadModelFromFileAndRegister(  const char* ModelConfig,
													  string &ModelName,
													  float &DimensionSphereRadius,
													  glm::vec3 &DimensionSphereCenter,
													  glm::vec3 &DimensionCorner );

	SubobjectConstructionInfo* LoadSubobjectFromFile( FILE *file );
	UnitTypeInfo* LoadUnitTypesFromFile( FILE *file );

	GLuint SetUpTexture2D( const std::string FileName, UINT &Width, UINT &Height ) const;
	GLuint SetUpTexture2D( const std::string FileName) const;
	GLuint SetUpTexture2D( const std::vector<std::string> FileNames ) const;

	void SetupGuiDummy( GAME_SUBOBJECT_INSTANCE *GuiSubobject );
	void SetupSubobjectParameters( SUBOBJECT_WITH_CONTROLLER &SubobjectWithController,
								   const SubobjectConstructionInfo &CustomInfo );

	std::pair<GLuint, std::vector<std::string> >
		 GetShaderName( const std::string ShaderPath, boost::unordered_map< string, std::pair<GLuint, std::vector<std::string> > > &LoadedShaders );

	CGameWorld::CPhysicsParam* LoadGameWorldPhysics( FILE *File );
	CGameWorld::CCameraParam* LoadGameWorldCamera( FILE *File );
	std::vector<CGameWorld::CGameObjectParam* > LoadGameWorldObjects( FILE *File );

	bool LoadKeyboardConfigFromFile( FILE *File, IGameLogic* GameLogic );
public:
	bool GetShablon( const char* FileShablon, vector<SAllShablon> &AllShablonResult );
    bool GetMapGUI( const char* FileControl, vector<SMapGUI> &MapGUIResult );

    /*
     * Loads full information for rendering, animating and process physic
     * on game objects will be crested during game world loading or
     * by kernel logic
     */
	bool LoadGameObjectsFromFile( const std::string FileName );

	/*
	 * Loads, compiles and links shader programs and saves a result as
	 * instances of IShaderConstructor in the Wirehouse to be used for creating
	 * shaders with specified parameters for a specific game object.
	 */
	bool LoadShadersFromFile( const std::string FileName );

	/*
	 * Loads game world description from file
	 */
	CGameWorld* LoadGameWorld( const std::string FileName );

	/*
	 * Loads configuration tables with specified names
	 */
	void LoadGameLogicConfigFromFile( IGameLogic* GameLogic,
			                          std::vector<std::string> ConfigFilesList );

};

#endif
